package com.easybbs.service.impl;

import com.easybbs.entity.config.WebConfig;
import com.easybbs.entity.constants.Constants;
import com.easybbs.entity.dto.SysSetting4EmailDto;
import com.easybbs.entity.enums.PageSize;
import com.easybbs.entity.po.EmailCode;
import com.easybbs.entity.po.UserInfo;
import com.easybbs.entity.query.EmailCodeQuery;
import com.easybbs.entity.query.SimplePage;
import com.easybbs.entity.query.UserInfoQuery;
import com.easybbs.entity.vo.PaginationResultVO;
import com.easybbs.exception.BusinessException;
import com.easybbs.mappers.EmailCodeMapper;
import com.easybbs.mappers.UserInfoMapper;
import com.easybbs.service.EmailCodeService;
import com.easybbs.utils.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.List;


/**
 * 邮箱验证码 业务接口实现
 */
@Service("emailCodeService")
public class EmailCodeServiceImpl implements EmailCodeService {

    //定义排查错误的日志
    private static final Logger logger = LoggerFactory.getLogger(EmailCodeServiceImpl.class);

    @Resource
    private EmailCodeMapper<EmailCode, EmailCodeQuery> emailCodeMapper;

    @Autowired
    private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

    //引入发送邮件包
    @Autowired
    private JavaMailSender javaMailSender;

    //注入配置类
    @Autowired
    private WebConfig webConfig;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<EmailCode> findListByParam(EmailCodeQuery param) {
        return this.emailCodeMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(EmailCodeQuery param) {
        return this.emailCodeMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<EmailCode> findListByPage(EmailCodeQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<EmailCode> list = this.findListByParam(param);
        PaginationResultVO<EmailCode> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(EmailCode bean) {
        return this.emailCodeMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<EmailCode> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.emailCodeMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<EmailCode> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.emailCodeMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 根据EmailAndCode获取对象
     */
    @Override
    public EmailCode getEmailCodeByEmailAndCode(String email, String code) {
        return this.emailCodeMapper.selectByEmailAndCode(email, code);
    }

    /**
     * 根据EmailAndCode修改
     */
    @Override
    public Integer updateEmailCodeByEmailAndCode(EmailCode bean, String email, String code) {
        return this.emailCodeMapper.updateByEmailAndCode(bean, email, code);
    }

    /**
     * 根据EmailAndCode删除
     */
    @Override
    public Integer deleteEmailCodeByEmailAndCode(String email, String code) {
        return this.emailCodeMapper.deleteByEmailAndCode(email, code);
    }

    /**
     * 判断邮件是否存在 然后进行邮件验证码发送
     *
     * @param email
     * @param type
     */
    @Override
    @Transactional(rollbackFor = Exception.class) //保证事务的回滚性
    public void sendEmailCode(String email, Integer type) {
        if (Constants.ZERO == type) {
            UserInfo userInfo = userInfoMapper.selectByEmail(email);
            if (userInfo != null) {
                throw new BusinessException("该邮箱已存在!");
            }
        }
        //生成5位随机数 用来作为验证码发送给用户
        String code = StringTools.getRandomString(Constants.LENGTH_5);

        //发送邮件验证码的方法
        sendEmailCodeDo(email, code);

        //修改验证码状态 0是为使用 1是已使用
        emailCodeMapper.disableEmailCode(email);
        //将验证码存入数据库
        EmailCode emailCode = new EmailCode();
        emailCode.setCode(code);
        emailCode.setEmail(email);
        emailCode.setStatus(Constants.ZERO);
        emailCode.setCreateTime(new Date());
        emailCodeMapper.insert(emailCode);
    }

    /**
     * 发送邮件的方法
     *
     * @param toEmail
     * @param code
     */
    private void sendEmailCodeDo(String toEmail, String code) {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //邮件发送人
            helper.setFrom(webConfig.getSendUserName());
            //邮件收件人
            helper.setTo(toEmail);
            //TODO 这里暂时写死 后续在改
            helper.setSubject("注册邮箱验证码");
            //TODO 邮箱内容  后续在改
            helper.setText("您的验证码是：" + code);
            helper.setSentDate(new Date());
            javaMailSender.send(message);
        } catch (Exception e) {
            logger.error("发送邮件失败", e);
            throw new BusinessException("邮件发送失败");
        }
    }

    /**
     * 检查邮箱验证码
     *
     * @param email
     * @param emailCode
     */
    @Override
    public void checkCode(String email, String emailCode) {
        EmailCode dbInfo = emailCodeMapper.selectByEmailAndCode(email, emailCode); //根据邮箱和验证码查询
        if (null == dbInfo) {
            throw new BusinessException("邮箱验证码错误");
        }

        if (dbInfo.getStatus() != Constants.ZERO && System.currentTimeMillis() - dbInfo.getCreateTime().getTime() > 1000 * 60 * Constants.LENGTH_15) {
            throw new BusinessException("邮箱验证码已失效");
        }
        emailCodeMapper.disableEmailCode(email);
    }

}